using System;
using System.Collections.Generic;
using System.Text;

namespace HappySprite.Simulation
{
    public class DefaultNarrowphase : Narrowphase
    {
        delegate bool CollisionHandler(CollisionEventArgs e);

        CollisionHandler[][] algorithms = new CollisionHandler[][] 
        {
            new CollisionHandler[6],
            new CollisionHandler[6],
            new CollisionHandler[6],
            new CollisionHandler[6],
            new CollisionHandler[6],
            new CollisionHandler[6]
        };

        public DefaultNarrowphase()
        {
            AddAlgorithm(CircleCircleAlgorithm.DetectCollision, ShapeType.Circle, ShapeType.Circle);
            AddAlgorithm(CircleBoxAlgorithm.DetectCollision, ShapeType.Circle, ShapeType.Box);
            AddAlgorithm(CircleHalfPlaneAlgorithm.DetectCollision, ShapeType.Circle, ShapeType.HalfPlane);
            AddAlgorithm(ConvexHalfPlaneAlgorithm.DetectCollision, ShapeType.Box, ShapeType.HalfPlane);
            AddAlgorithm(FalseAlgoritm, ShapeType.HalfPlane, ShapeType.HalfPlane);
        }

        public override bool DetectCollision(CollisionEventArgs e)
        {
            int index1 = (int)e.This.CollisionShape.ShapeType;
            int index2 = (int)e.Other.CollisionShape.ShapeType;

            CollisionHandler algorithm = algorithms[index1][index2];

            if (algorithm != null)
            {
                if (index1 <= index2)
                {
                    return algorithm(e);
                }
                else
                {
                    e.Reverse();
                    bool result = algorithm(e);
                    e.Reverse();
                    return result;
                }
            }

            return ConvexConvexAlgorithm.DetectCollision(e);
        }

        void AddAlgorithm(CollisionHandler algorithm, ShapeType shape1, ShapeType shape2)
        {
            algorithms[(int)shape1][(int)shape2] = algorithm;

            if (shape1 != shape2)
                algorithms[(int)shape2][(int)shape1] = algorithm;
        }

        static bool FalseAlgoritm(CollisionEventArgs e)
        {
            return false;
        }
    }
}
